#ifndef _UART_H
#define _UART_H

#include <device.h>
#include <tty.h>

#ifdef __TOP_HALF__ 

struct uart {
	unsigned int index;
	void (*init)(struct device *dev);
	int (*getc)(struct device *dev);
	int (*putc)(struct device *dev, unsigned int c);
	void (*flush)(struct device *dev);
};

#else 

#define MAJOR_UART			(2)		

#define UART_CHAR_BREAK		(1)
#define UART_CHAR_ERROR		(2)

#define UART_PARITY_NO		(0)
#define UART_PARITY_ODD		(1)
#define UART_PARITY_EVEN	(2)

struct char_with_flags {
	unsigned char ch;
	unsigned char fg;
};

#define UIOGDBITS	_IOR('u', 1, uint8_t)
#define UIOSDBITS	_IOW('u', 2, uint8_t)
#define UIOGSBITS	_IOR('u', 3, uint8_t)
#define UIOSSBITS	_IOW('u', 4, uint8_t)
#define UIOGBAUD	_IOR('u', 5, uint32_t)
#define UIOSBAUD	_IOW('u', 6, uint32_t)
#define UIOGPBIT	_IOR('u', 7, uint8_t)
#define UIOSPBIT	_IOW('u', 8, uint8_t)
#define UIOSBREAK	_IO('u', 9) 
#define UIOGCHCF	_IOR('u', 10, struct char_with_flags)

struct uart {
	struct tty tty;
	void *membase;
	void *priv;
};

struct uart_driver;

struct uart_operations {
	int  (*is_tx_full)(struct uart *uart);
    void (*stop_tx)(struct uart *uart);
    void (*start_tx)(struct uart *uart);
	int  (*is_tx_empty)(struct uart *uart);
	
	int	 (*is_rx_empty)(struct uart *uart);
	void (*start_rx)(struct uart *uart);
    void (*stop_rx)(struct uart *uart);
	
    int  (*startup)(struct uart *uart);
    void (*shutdown)(struct uart *uart);

	int  (*get_data_bits)(struct uart *uart);
	int  (*set_data_bits)(struct uart *uart, uint8_t bits);
	int  (*get_stop_bits)(struct uart *uart);
	int  (*set_stop_bits)(struct uart *uart, uint8_t bits);
	int  (*get_baudrate)(struct uart *uart);
	int  (*set_baudrate)(struct uart *uart, uint32_t baud);
	int  (*get_parity_bit)(struct uart *uart);
	int  (*set_parity_bit)(struct uart *uart, uint8_t parity);
	
	int (*send_char)(struct uart *uart, unsigned char ch, unsigned char fg);
	int (*recv_char)(struct uart *uart, unsigned char *ch, unsigned char *fg);
	
	int (*ioctl)(struct uart *uart, unsigned int cmd, unsigned int arg);
	int (*match)(struct device *dev, struct uart_driver *udrv);
	int (*probe)(struct uart *uart, struct uart_driver *udrv);
};

struct uart_driver {
	struct tty_driver tdrv;
	struct uart_operations *ops;
};

#define tty_to_uart(_tty)					container_of(_tty, struct uart, tty)
#define tty_driver_to_uart_driver(_tdrv)	container_of(_tdrv, struct uart_driver, tdrv)
#define uart_to_tty(_uart)					(&((_uart)->tty))
#define uart_driver_to_tty_driver(_udrv)	(&((_udrv)->tdrv))

#define tty_to_uart_driver(_tty) (tty_driver_to_uart_driver(tty_to_tty_driver(_tty)))

extern struct tty_operations uart_ops;

#endif 

#endif /* _UART_H */

